4.1.4 请求主体
请求和响应的主体都由 Request
结构的 Body
字段表示,这个字段是一个 io.Read
Closer接口,该接口既包含了 Reader
接口,也包含了 Closer
接口。其中 Reader
接口拥有 Read
方法,这个方法接受一个字节切片为输入,并在执行之后返回被读取内容的字节数以及一个可选的错误作为结果;而 Closer
接口则拥有 Close
方法,这个方法不接受任何参数,但会在出错时返回一个错误。同时包含 Reader
接口和 Closer
接口意味着用户可以对 Body
字段调用 Read
方法和 Close
方法。作为例子,代码清单4-3展示了如何使用 Read
方法读取请求主体的内容。
代码清单4-3 读取请求主体中的数据
package main
import (
"fmt"
"net/http"
)
func body(w http.ResponseWriter, r *http.Request) {
len := r.ContentLength
body := make([]byte, len)
r.Body.Read(body)
fmt.Fprintln(w, string(body))
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/body", body)
server.ListenAndServe()
}
这段程序首先通过 ContentLength
方法获取主体数据的字节长度,接着根据这个长度创建一个字节数组,然后调用 Read
方法将主体数据读取到字节数组中。
因为 GET
请求并不包含报文主体,所以如果我们想要测试这个服务器,就需要给它发送 POST
请求。正如之前所说,浏览器一般需要通过HTML表单才能发送 POST
请求,但是因为本书在下一节才会开始介绍HTML表单,所以这里我们暂且就先使用HTTP客户端来测试服务器。市面上可用的HTTP客户端非常多,既有桌面版的图形HTTP客户端,也有浏览器插件或者扩展,还有cURL等命令行程序可供选择。
作为例子,以下命令展示了如何使用cURL向服务器发送一条 POST
请求:
$ curl -id "first_name=sausheong&last_name=chang" 127.0.0.1:8080/body
cURL在接收到响应之后将向用户返回一段完整并且未经处理的HTTP响应,其中位于空行之后的就是HTTP的主体。以下展示的就是上面的cURL命令返回的响应:
HTTP/1.1 200 OK
Date: Tue, 13 Jan 2015 16:11:58 GMT
Content-Length: 37
Content-Type: text/plain; charset=utf-8
first_name=sausheong&last_name=chang
因为Go语言提供了诸如 FormValue
和 FormFile
这样的方法来提取通过 POST
方法提交的表单,所以用户一般不需要自行读取主体中未经处理的表单,本章接下来的一节就会介绍 FormValue
和 FormFile
等方法。